<?php
/*
 * @Author: 1086 cchcc@qq.com
 * @Date: 2024-04-22 10:38:36
 * @LastEditors: 1086 cchcc@qq.com
 * @LastEditTime: 2024-05-16 17:38:27
 * @FilePath: \erp\api\php\app\pos_v1\controller\classPosOrder.php
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
declare(strict_types=1);
namespace app\pos_v1\controller;

use think\facade\Db; //门面模式
use app\pos_v1\model\classPosOrder as mysql; //导入模型
use think\Request;
use function PHPSTORM_META\type;

// 公共类-销售订单
class classPosOrder
{
    // POS销售-保存销售单
    public function PosOrder($param = [])
    {
        //验证规则
        $validate = new \app\pos_v1\validate\classPosOrder;
        if (!$validate->check($param)) {
            // 验证不过关提示
            $apidb = [
                'code' => 201, //状态码
                'msg' => "请求参数验证不通过!",
                'validate' => $validate->getError(),
            ];
            return $apidb;
        }
        $operate = $param["operation"]; //操作类型_A结算保存B挂单保存
        $state = ''; //更新状态
        switch ($operate) {
            case "A":
                $state = 'D';
                break;
            case "B":
                $state = 'A';
                break;
            default:
                $apidb = [
                    'code' => 201, //状态码
                    'msg' => "操作类型非法,不能继续操作", //状态信息
                ];
                return $apidb;
        }
        // 查单头
        $sqldb = mysql::where(['dbid' => $param["dbid"], 'sign' => $param["sign"],])->find();
        // 查询返回空
        if ($sqldb == null) {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "订单不存在", //状态信息
            ];
            return $apidb;
        }

        // 单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)F已整单退货
        if ($sqldb['state'] == 'B') {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "已结算单据,不能继续操作", //状态信息
            ];
            return $apidb;
        }
        // 单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)F已整单退货
        if ($sqldb['state'] == 'F') {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "已退货单据,不能继续操作", //状态信息
            ];
            return $apidb;
        }

        $data_now = $sqldb->toArray(); //旧单数据另存为
        $data = [];
        $insert_data = [];
        $cr = $param["goods_db"]; //订单明细数据
        for ($i = 0; $i < count($cr); $i++) {
            $insert_data[$i]["order_dbid"] = $data_now["dbid"]; //对应订单数据编号
            $insert_data[$i]["goods_dbid"] = $cr[$i]["goods_dbid"]; //商品数据编号
            $insert_data[$i]["number"] = $cr[$i]["number"]; //数量
            $insert_data[$i]["prc_sale"] = $cr[$i]["prc_sale"]; //档案-零售价（原零售价）
            $insert_data[$i]["prc_sale_actual"] = $cr[$i]["prc_sale_actual"]; //实际-零售价
            $insert_data[$i]["unit"] = $cr[$i]["unit"]; //单位
            $insert_data[$i]["unit_pack"] = $cr[$i]["unit_pack"]; //是否大单位_A是B否
            $insert_data[$i]["goods_name"] = $cr[$i]["goods_name"]; //单位
            $insert_data[$i]["in_code"] = $cr[$i]["in_code"]; //录入码
            $insert_data[$i]["barcode"] = $cr[$i]["barcode"]; //条码
            $insert_data[$i]["remark"] = $cr[$i]["remark"]; //单行备注
            $insert_data[$i]["prc_sale_sum"] = (float) bcmul((string) $cr[$i]["prc_sale"], (string) $cr[$i]["number"], 4); //档案-零售价（原零售价）-小计=档案-零售价（原零售价）*数量
            $insert_data[$i]["prc_sale_actual_sum"] = (float) bcmul((string) $cr[$i]["prc_sale_actual"], (string) $cr[$i]["number"], 4); //实际-零售价-小计=实际-零售价*数量
        }
        $total_price = 0; //整单总价_原始价
        $total_price_new = 0; //整单总价_实收价
        $total_discount = ""; //整单折扣
        $prc_sale_sum = 0; //档案-零售价-小计
        for ($i = 0; $i < count($insert_data); $i++) {
            $total_price += $insert_data[$i]["prc_sale_actual_sum"];
            $prc_sale_sum += $insert_data[$i]["prc_sale_sum"];
        }

        // [整单总价_实收价]=[整单总价_原始价]-[减免金额]
        $total_price_new = (float) bcsub((string) $total_price, (string) $data_now["price_reduce_val"], 4);
        //[整单折扣]=[整单总价_实收价]/[整单总价_原始价]
        $total_discount = bcdiv((string) $total_price_new, (string) $total_price, 4);


        // 写入订单头成功-得到订单号后-写入订单明细
        // 删除旧的明细
        $deleteok = Db::table('pos__p_sell_order_detail')->where(['order_dbid' => $sqldb["dbid"]])->delete();
        //分批写入每次最多100条数据
        $sql_insert_goods_db = Db::name('pos__p_sell_order_detail')
            ->strict(false)
            ->limit(100)
            ->insertAll($insert_data);
        if ($sql_insert_goods_db) {
            $code = 200;
            $msg = "单据保存-成功";
            // 更新订单头字段-明细写入长度
            $mysql_data_now = mysql::where(['dbid' => $data_now["dbid"]])->find();
            $mysql_data_now->detail_length_insert = $sql_insert_goods_db; //明细写入长度

            $mysql_data_now->total_price = $total_price; //整单总价_原始价
            $mysql_data_now->total_price_new = $total_price_new; //整单总价_实收价
            $mysql_data_now->total_discount = $total_discount; //整单折扣

            $mysql_data_now->time_new = time(); //计算属性-创建时间
            $mysql_data_now->time_up = time(); //计算属性-修改时间
            $mysql_data_now->detail_length_query = count($param["goods_db"]); //明细请求长度
            // 'remark= (isset($query['table_header']['remark']) && !empty($query['table_header']['remark'])) ? $query['table_header']['remark'] : '单据备注'; //单据备注
            $mysql_data_now->remark = $param["remark"] ? $param["remark"] : '单据备注'; //单据备注
            // $sqldb->operator= $query["operator"]   ? $query["operator"]  : '门店操作员'; //门店操作员
            // $mysql_data_now->sign = '-'; //改单签名串
            $mysql_data_now->state = $state; //单据状态_A挂单B已结算C预下单号D草稿单
            $mysql_data_now->type = $param["type"]; //单据类型_A1销售B1退货
            $mysql_data_now->save();
            $data = mysql::where(['dbid' => $data_now["dbid"]])->find();
            //设置需要输出的属性
            $data = $data->visible([
                // 'id', //主键
                "dbid",
                "sign",
                // "type",
                // "state",
                // "time_new",
                // "time_up",
                // "detail_length_query",
                // "detail_length_insert",
                // "remark",
                // "operator",
                // "total_price",
                // "total_discount",
            ]);
            // 设置需要隐藏的输出属性
            $data = $data->hidden([
                //     'id', //主键
            ]);
            // 设置需要附加的输出属性
            $data = $data->append([
                // 'goods_db', //附加字段-单据明细
            ]);
            // POS销售单据关联商品
            // $order_detail = Db::table('pos__p_sell_order_detail')->where(['order_dbid' => $sqldb["dbid"]])->select();
            // $data["goods_db"] = $order_detail->toArray();
            if ($sql_insert_goods_db != count($param["goods_db"])) {
                $code = 201;
                $msg = "订单明细写入-成功-但条目不相等";
                $data = [];
            }
        } else {
            $code = 201;
            $msg = "订单明细写入-失败";
            $data = [];
        }
        // API信息
        $help = [
            "code" => "错误代码",
            "time" => "接口运行时间",
            "msg" => "状态信息",
            "query=接口请求参数包" => [
                "type" => "单据类型_A1销售B1退货",
                "operation" => "操作类型_A结算保存B挂单保存",
                "dbid" => "单号",
                "sign" => "改单签名串",
                "remark" => "单据备注",
                "goods_db=商品数据数组包" => [
                    [
                        "goods_dbid" => "商品数据编号",
                        "number" => "数量",
                        "prc_sale" => "档案-零售价（原零售价）",
                        "prc_sale_actual" => "实际-零售价",
                        "unit" => "单位",
                        "unit_pack" => "是否大单位_A是B否",
                        "goods_name" => "商品名称",
                        "in_code" => "录入码",
                        "barcode" => "条码",
                        "remark" => "单行备注"
                    ]
                ]
            ],
            "db=接口回调核心数据包" => [
                "state" => "单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)E已整单退货",
                "dbid" => "数据编号.唯一(系统单号)",
                "sign" => "改单签名串",
                "type" => "单据类型_A1销售B1退货",
                "detail_length_query" => "明细请求长度",
                "detail_length_insert" => "明细写入长度",
                "operator" => "门店操作员",
                "total_price" => "整单总价",
                "total_discount" => "整单折扣",
                "tm_code" => "终端机器码",
                "tm_id" => "机器号",
                "time_new" => "计算属性-创建时间",
                "time_up" => "计算属性-修改时间",
                "remark" => "单据备注",
                "goods_db=商品数据数组包" => [
                    "order_dbid" => "对应订单数据编号",
                    "goods_dbid" => "商品数据编号",
                    "number" => "数量",
                    "prc_sale" => "档案-零售价（原零售价）",
                    "prc_sale_actual" => "实际-零售价",
                    "prc_sale_actual_sum" => "实际-零售价-小计",
                    "unit" => "单位",
                    "in_code" => "录入码",
                    "barcode" => "条码",
                    "remark" => "单行备注",
                    "goods_name" => "商品名称",
                    "unit_pack" => "是否大单位_A是B否",
                ]
            ]
        ];
        $apidb = [
            'code' => $code,
            'time' => time(),
            'msg' => $msg,
            'db' => $data,
            'query' => request()->param(), //请求参数
            // "接口信息" => ["name" => "保存销售单", "notice" => "部分字段可能不返回，没用到的字段不要预设，部分描述文字可能有错误。", "help" => $help], //API信息
        ];
        return $apidb;
    }
}
